package net.xconcepts.stockdata.model.input;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import net.xconcepts.stockdata.model.analysis.symbol.Symbol;
import net.xconcepts.stockdata.model.tick.SymbolTick;
import net.xconcepts.stockdata.model.tick.TickDataField;
import au.com.bytecode.opencsv.CSVReader;


/**
 * Data feed which can retrieve
 * @author Steven
 *
 */
public class HistoricDataFeed {

	private Calendar mCurrentTime = Calendar.getInstance();
	private final Date mEndDate;
	private final File mInputDir;
	private static final SimpleDateFormat mSDF = new SimpleDateFormat("yyyy-MM-dd");
	private static final Hashtable<Integer, TickDataField> mHeaderMap = new Hashtable<Integer, TickDataField>();
	{
		mHeaderMap.put(1, TickDataField.Open);
		mHeaderMap.put(2, TickDataField.High);
		mHeaderMap.put(3, TickDataField.Low);
		mHeaderMap.put(4, TickDataField.Close);
		mHeaderMap.put(5, TickDataField.Volume);
	}
	
	public HistoricDataFeed (File inputDir, Date initialDate, Date endDate) {
		if(!inputDir.isDirectory()) throw new IllegalArgumentException();
		mInputDir = inputDir;
		mCurrentTime.setTime(initialDate);
		mEndDate = endDate;
	}
	
	
	public boolean hasNext() {
		return mCurrentTime.getTime().before(mEndDate);
	}
	
	/**
	 * 
	 * @return null if no ticks remain
	 */
	public Map<Symbol, SymbolTick> next() {
		if (!hasNext()) return null;
		
		String date = mSDF.format(mCurrentTime.getTime());
		String inputDir = mInputDir.getAbsolutePath();
		File file = new File(inputDir + "/" + date + ".csv");
		while(!(file.exists())) { //increment until next file
			mCurrentTime.add(Calendar.DATE, 1);
			date = mSDF.format(mCurrentTime);
			file = new File(inputDir + date + ".csv");
			if (!hasNext()) return null;
		}
		
		try {
			CSVReader reader = new CSVReader(new FileReader(file));
			List<String[]> tickData = reader.readAll();
			Map<Symbol, SymbolTick> ticks = new HashMap<Symbol, SymbolTick>();
			
			for(String[] lineData : tickData) {
				SymbolTick symbolTick = lineToTickData(mCurrentTime.getTime(), lineData);
				ticks.put(symbolTick.getSymbol(), symbolTick);
			}
			
			reader.close();
			
			return ticks;
		} catch (IOException e) {
			System.out.println("CRITICAL ERROR IN HISTORIC DATA FEED");
			e.printStackTrace();
		} finally {
			mCurrentTime.add(Calendar.DATE, 1);
		}
		
		return null;
	}
	
	/** Converts a line from the CSVReader to TickData 
	 * @throws ParseException */
	private SymbolTick lineToTickData(Date timeStamp, String[] columns) {
		Hashtable<TickDataField, Double> tickData = new Hashtable<TickDataField, Double>();
		
		for (Entry<Integer, TickDataField> entry : mHeaderMap.entrySet()) {
			tickData.put(entry.getValue(), Double.parseDouble(columns[entry.getKey()]));
		}
		
		SymbolTick tick;
		tick = new SymbolTick(columns[0], timeStamp, tickData);
		return tick;
	}
}
